From c48f8a0105a4c3eee2354654ac0d4b68e1f91542 Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Tue, 17 Mar 2009 10:36:20 +0000 Subject: [PATCH] xend: Implement DGRAM (connectionless) type socket listeners Introduce SocketDgramListener and UnixDgramListener classes. We already have STREAM (connection) type socket listener classes in the source tree, but we need DGRAM (connectionless) type listeners to receive udev events. Signed-off-by: Yosuke Iwamatsu --- tools/python/xen/web/connection.py | 37 ++++++++++++++++++++++++++++++ tools/python/xen/web/unix.py | 32 ++++++++++++++++++-------- 2 files changed, 60 insertions(+), 9 deletions(-) diff --git a/tools/python/xen/web/connection.py b/tools/python/xen/web/connection.py index 7d5702fce0..e507323e91 100644 --- a/tools/python/xen/web/connection.py +++ b/tools/python/xen/web/connection.py @@ -292,3 +292,40 @@ def hostAllowed(addrport, hosts_allowed): return True log.warn("Rejected connection from %s (%s).", addrport[0], fqdn) return False + + +class SocketDgramListener: + """A connectionless server socket, running listen in a thread. + """ + + def __init__(self, protocol_class): + self.protocol = protocol_class() + self.sock = self.createSocket() + threading.Thread(target=self.main).start() + + + def close(self): + try: + self.sock.close() + except: + pass + + + def createSocket(self): + raise NotImplementedError() + + + def main(self): + try: + while True: + try: + data = self.sock.recv(BUFFER_SIZE) + self.protocol.dataReceived(data) + except socket.error, ex: + if ex.args[0] not in (EWOULDBLOCK, EAGAIN, EINTR): + break + finally: + try: + self.close() + except: + pass diff --git a/tools/python/xen/web/unix.py b/tools/python/xen/web/unix.py index 12b6e9694e..180c0858eb 100644 --- a/tools/python/xen/web/unix.py +++ b/tools/python/xen/web/unix.py @@ -27,16 +27,19 @@ from xen.util import mkdir import connection -def bind(path): - """Create a Unix socket, and bind it to the given path. The socket is -created such that only the current user may access it.""" +def bind(path, type = socket.SOCK_STREAM): + """Create a Unix socket, and bind it to the given path. + The socket is created such that only the current user may access it.""" - parent = os.path.dirname(path) - mkdir.parents(parent, stat.S_IRWXU, True) - if os.path.exists(path): - os.unlink(path) + if path[0] == '\0': # Abstract namespace is used for the path + pass + else: + parent = os.path.dirname(path) + mkdir.parents(parent, stat.S_IRWXU, True) + if os.path.exists(path): + os.unlink(path) - sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) + sock = socket.socket(socket.AF_UNIX, type) sock.bind(path) return sock @@ -48,8 +51,19 @@ class UnixListener(connection.SocketListener): def createSocket(self): - return bind(self.path) + return bind(self.path, socket.SOCK_STREAM) def acceptConnection(self, sock, _): connection.SocketServerConnection(sock, self.protocol_class) + + +class UnixDgramListener(connection.SocketDgramListener): + def __init__(self, path, protocol_class): + self.path = path + connection.SocketDgramListener.__init__(self, protocol_class) + + + def createSocket(self): + return bind(self.path, socket.SOCK_DGRAM) + -- 2.30.2